//
// Created by Leaf on 2025/8/18.
//

#include "PIR_Motion.h"

#define PIR_STATE_NORMAL LOW   // PIR传感器常态
#define PIR_STATE_DETECTED HIGH // PIR传感器检测到运动状态

// 静态成员变量定义
volatile bool PIRMotion::motion_detected = false;
PIRMotionCallback PIRMotion::motion_callback = nullptr;  // 静态回调函数指针初始化

// PIRMotion类构造函数，初始化PIR传感器引脚
PIRMotion::PIRMotion(uint8_t pin) : pir_pin(pin), use_interrupt(true) {
}

// 初始化PIR传感器，支持选择是否使用中断
// useInterrupt: true表示使用中断模式，false表示使用轮询模式
// interruptPriority: 中断优先级设置，数值越小优先级越高，范围通常为0-7
void PIRMotion::begin(bool useInterrupt, uint8_t interruptPriority) {
    use_interrupt = useInterrupt;
    pinMode(pir_pin, INPUT);  // 设置PIR引脚为输入模式
    
    if (use_interrupt) {
        motion_detected = false; // 清除运动检测标志
        attachInterrupt(digitalPinToInterrupt(pir_pin), motionDetectedISR, RISING); // 设置上升沿触发中断
        // ESP32 Arduino框架中不直接支持设置中断优先级，需要使用ESP-IDF函数
        // 这里保留参数用于未来扩展或兼容其他平台
    }
}

// 检查是否检测到运动
// 返回值: true表示检测到运动，false表示未检测到运动
bool PIRMotion::isDetected() {
    if (use_interrupt) {
        // 中断模式
        bool detected = motion_detected;
        if (detected) {
            motion_detected = false; // 读取后清除标志位
        }
        return detected;
    } else {
        // 轮询模式
        return digitalRead(pir_pin) == PIR_STATE_DETECTED;
    }
}

// 注册运动检测回调函数
// callback: 用户定义的回调函数，当检测到运动时会被调用
void PIRMotion::onMotionDetected(PIRMotionCallback callback) {
    motion_callback = callback;
}

// 中断服务例程
void PIRMotion::motionDetectedISR() {
    motion_detected = true;
    
    // 如果注册了回调函数，则调用它
    // 注意：在中断服务例程中应避免执行耗时操作
    if (motion_callback) {
        motion_callback();
    }
}